Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Drawing.Imaging

Public Class PointChooseForm
    Inherits System.Windows.Forms.Form
    Implements IDisposable

#Region " Windows Form Designer generated code "

    Public Sub New(Optional ByVal background As Image = Nothing)
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

        If background IsNot Nothing Then
            Me.BackgroundImage = background
            Me.BackgroundImageLayout = ImageLayout.None
            Me.Size = New Size(BackgroundImage.Width + 10, BackgroundImage.Height + 10)
        Else
            Me.Close()
        End If
    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.SuspendLayout()
        '
        'PointChooseForm
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(6, 16)
        Me.ClientSize = New System.Drawing.Size(398, 359)
        Me.Font = New System.Drawing.Font("Microsoft Sans Serif", 10.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog
        Me.MaximizeBox = False
        Me.MinimizeBox = False
        Me.ResumeLayout(False)

    End Sub

#End Region

#Region "Declarations"
    Private Enum ChangeStyle
        MouseMove
        RGB
        HSV
        None
    End Enum

    Private changeType As ChangeStyle = ChangeStyle.None
    Private selectedPoint As Point

    Private isInUpdate As Boolean = False

    Private g As Graphics
    Private colorRegion As Region
    Private brightnessRegion As Region
    Private colorImage As Bitmap

    ' Keep track of the current mouse state. 
    Public Enum MouseState
        MouseUp
        ClickOnColor
        DragInColor
        ClickOnBrightness
        DragInBrightness
        ClickOutsideRegion
        DragOutsideRegion
    End Enum
    Private currentState As MouseState = MouseState.MouseUp

    Private centerPoint As Point
    Private radius As Integer

    Private colorRectangle As Rectangle
    Private brightnessRectangle As Rectangle
    Private selectedColorRectangle As Rectangle
    Private brightnessX As Integer
    Private brightnessScaling As Double

    ' selectedColor is the actual value selected
    ' by the user. fullColor is the same color, 
    ' with its brightness set to 255.
    Private selectedColor As Color = Drawing.Color.White
    Private fullColor As Color = selectedColor


    ' Locations for the two "pointers" on the form.
    Public CurrentSelectedPoint As Point = New Point(3, 3)
    Private brightnessPoint As Point = New Point(3, 3)
#End Region

    Private Sub frmMain_Load( _
     ByVal sender As System.Object, ByVal e As System.EventArgs) _
     Handles MyBase.Load

        Dim ColorRectangle As Rectangle = _
     New Rectangle(Me.Location, Me.Size)


        Dim path As GraphicsPath

        ' Store away locations for later use. 
        Me.colorRectangle = ColorRectangle
        path = New GraphicsPath()
        path.AddRectangle(ColorRectangle)
        colorRegion = New Region(path)

    End Sub

    Private Sub HandleMouse( _
     ByVal sender As Object, ByVal e As MouseEventArgs) _
     Handles MyBase.MouseMove, MyBase.MouseDown

        ' If you have the left mouse button down, 
        ' then update the selectedPoint value and 
        ' force a repaint of the color wheel.
        If e.Button = Windows.Forms.MouseButtons.Left Then
            changeType = ChangeStyle.MouseMove
            selectedPoint = New Point(e.X, e.Y)
            Me.Invalidate()
        End If
    End Sub

    Private Sub frmMain_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseUp
        ' Indicate that the user has
        ' released the mouse.
        currentState = MouseState.MouseUp
        changeType = ChangeStyle.None
    End Sub

    Private Sub ColorChooser1_Paint( _
     ByVal sender As Object, _
     ByVal e As PaintEventArgs) Handles MyBase.Paint
        ' Depending on the circumstances, force a repaint
        ' of the color wheel passing different information.
        Select Case changeType
            Case ChangeStyle.MouseMove, ChangeStyle.None
                ' You've moved the mouse. 
                ' Now update the screen to match.

                Dim newColorPoint As Point

                newColorPoint = CurrentSelectedPoint

                ' Store this away for later use.
                g = e.Graphics
                Me.g = g

                If currentState = MouseState.MouseUp Then
                    If Not selectedPoint.IsEmpty Then
                        '   If colorRegion.IsVisible(mousePoint) Then
                        currentState = MouseState.ClickOnColor
                        '    End If
                    End If
                End If

                Select Case currentState

                    Case MouseState.ClickOnColor, MouseState.DragInColor
                        ' Calculate new color information
                        ' based on selected color, which may have changed.
                        newColorPoint = selectedPoint
                End Select

                ' On the way out, set the new state.
                Select Case currentState
                    Case MouseState.ClickOnColor
                        currentState = MouseState.DragInColor
                    Case MouseState.ClickOutsideRegion
                        currentState = MouseState.DragOutsideRegion
                End Select

                ' Store away the current points for next time.
                CurrentSelectedPoint = newColorPoint

                ' Draw the gradients and points. 
                UpdateDisplay()
        End Select
    End Sub

#Region " Generic Subs"
    Private Sub UpdateDisplay()
        DrawColorPointer(CurrentSelectedPoint)
        Me.Text = CurrentSelectedPoint.X & "," & CurrentSelectedPoint.Y
    End Sub

    Private Sub DrawColorPointer(ByVal pt As Point)
        ' Given a point, draw the color selector. 
        ' The constant SIZE represents half
        ' the width -- the square will be twice
        ' this value in width and height.
        Const SIZE As Integer = 3
        g.DrawRectangle(Pens.Red, _
     pt.X - SIZE, pt.Y - SIZE, _
     SIZE * 2, SIZE * 2)
    End Sub

    Private Overloads Sub Dispose()
        ' Dispose of graphic resources
        If Not colorImage Is Nothing Then
            colorImage.Dispose()
        End If
        If Not colorRegion Is Nothing Then
            colorRegion.Dispose()
        End If
        If Not brightnessRegion Is Nothing Then
            brightnessRegion.Dispose()
        End If
        If Not g Is Nothing Then
            g.Dispose()
        End If
    End Sub
#End Region

End Class
